import React from 'react';
import PropTypes from 'prop-types';

import cn from 'classnames';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import fetchFer from 'fermionjs/lib/fetch';
import { searchStringBuilder } from '@kuiper-components/page-table';
import Table from '@knownsec/react-component/dist/Table';
import Pagination from '@knownsec/react-component/dist/Pagination';
import EmptyData from '../../../components/empty/EmptyData';

import WarningCount from '../WarningCount';
import { datetime } from '../../../../common/formatter';
import ColSecurityStatus from '../../../components/ColSecurityStatus';
import DownOnce from '../../../components/DownOnce';
import Breadcrumb, { Item } from '../../../components/Breadcrumb';
import { TASK_KEY_LABEL_MAP } from '../../../../common/constants';
import collectType from '../../../../common/collectType';
import TableToolbox from './TableToolbox';
import s from './style.module.css';
import VulMonitorSetting from '../../../components/TaskSettingsViewer/VulMonitorSettings';
import CopyBoard from '../../../components/CopyBoard';

class TaskHistory extends React.PureComponent {
	static propTypes = {
		className: PropTypes.string,
		history: PropTypes.shape({
			push: PropTypes.func.isRequired,
			replace: PropTypes.func.isRequired,
		}).isRequired,
		location: PropTypes.shape({
			search: PropTypes.string.isRequired,
		}).isRequired,
		match: PropTypes.shape({
			params: PropTypes.shape({
				taskType: PropTypes.string,
				jobId: PropTypes.string,
			}).isRequired,
		}).isRequired,
	};

	static defaultProps = {
		className: '',
		rolesMap: {},
	};

	constructor(props) {
		super(props);
		const {
			match: {
				params: { taskType, jobId },
			},
			location: { search },
		} = props;
		this.taskType = taskType;
		this.routePrefix = `/weakness/${taskType}/history/${jobId}`;
		const searchVal = new URLSearchParams(search);
		this.defaultFilter = {
			taskType,
			OR: [{ securityStatus: 'safe' }, { securityStatus: 'warning' }],
			targetSearch: searchVal.get('targetSearch'),
		};
		this.state = {
			page: 1,
			perPage: 10,
			count: 0,
			loading: false,
			type: 'empty',
			filter: searchVal.get('filter'),
			tableData: [],
			otherQuery: {
				endTime_lt: '',
				endTime_gte: '',
				securityStatus: '',
				targetSearch: '',
				name: '',
			},
		};
	}

	getRefetch = x => (this.refetch = x);
	columnsBuilder = () => [
		{
			title: '资产名称',
			dataIndex: 'job',
			key: 'job',
			render(job) {
				return (
					<div className={s.target} title={job?.note}>
						{job?.note}
					</div>
				);
			},
		},
		{
			title: '资产地址',
			dataIndex: 'target',
			key: 'target',
			render(target) {
				return (
					<CopyBoard
						className={cn(s.vam, s.lh1)}
						text={target}
						maxWidth="12rem"
					/>
				);
			},
		},
		{
			title: '监测方式',
			dataIndex: 'triggerType',
			key: 'triggerType',
			render(triggerType, { taskSettings: { collect } }) {
				return (
					<div className={s.triggerType}>
						{collectType({
							triggerType,
							collect,
						})}
					</div>
				);
			},
		},
		{
			title: this.taskType === 'vul' ? '漏洞数' : '威胁数',
			dataIndex: 'result',
			key: 'count',
			render(result) {
				const data = result?.warnings?.reduce((obj, x) => {
					if (!x?.level) return obj;
					if (!obj[x.level]) {
						obj[x.level] = {
							warningIgnoredCount: 0,
							warningCount: 0,
						};
					}
					obj[x.level].warningCount += 1;
					if (x.ignoredTime) {
						obj[x.level].warningIgnoredCount += 1;
					}
					return obj;
				}, {});
				return <WarningCount data={data} />;
			},
		},
		{
			title: '安全状态',
			dataIndex: 'securityStatus',
			key: 'securityStatus',
			render(securityStatus, { taskSessionId, taskType }) {
				return (
					<ColSecurityStatus
						taskType={taskType}
						securityStatus={securityStatus}
						tsid={taskSessionId}
						className={s.subVam}
					/>
				);
			},
		},
		{
			title: '监测完成时间',
			dataIndex: 'endTime',
			key: 'updateTime',
			width: 200,
			render(endTime) {
				return <span>{datetime(endTime)}</span>;
			},
		},
		{
			title: '操作',
			dataIndex: 'target',
			key: '__actions__',
			width: 140,
			render: (target, record) => {
				return (
					<div className={s.actions}>
						<Link
							to={{pathname: `/weakness/vul/detail/${record?._id}`,
							search: `tsid=${record?.taskSessionId}`,
							state: {refer: location?.href?.split('?')[1], jobId: record?.jobId}}}
							className={s.linkBtn}
						>
							详情
						</Link>
						{/* <VulMonitorSetting
							className={s.linkBtn}
							host={target}
							taskType={record?.taskType}
							isLatestTask={record?.isLatestTask}
							jobId={record?.jobId}
							note={record?.job?.note || ''}
							triggerType={record?.triggerType}
							taskSettings={record?.taskSettings}
							alertSettings={record?.alertSettings}
						>
							配置
						</VulMonitorSetting> */}
						<DownOnce
							className={s.linkBtn}
							record={{ ...record, note: record?.job?.note }}
						/>
					</div>
				);
			},
		},
	];

	searchStringBuilder = searchStringBuilder.bind(
		this,
		this.props.location.search
	);

	handleFilterChange = filter => {
		const search = this.searchStringBuilder({
			filter: JSON.stringify(filter),
			page: 1,
			sort: 'ENDTIME_DESC',
		});
		this.setState({ filter, page: 1, perPage: 10 });
		this.getData(1, 10, filter);
		this.props.history.replace(`${this.routePrefix}?${search}`);
	};

	turnToUrlparam = obj => {
		let urls = '';
		const hasValKey = Object.keys(obj)
			.filter(
				item =>
					obj[item] ||
					obj[item] === false ||
					(typeof obj[item] !== 'string' && obj[item] == 0)
			)
			.map(i => {
				return i + '=' + obj[i];
			});
		urls = hasValKey.join('&');
		return urls;
	};

	getData = (page, limit, obj = undefined) => {
		let querydata = {
			taskType: this.taskType,
			page: page || 1,
			count: limit || 10,
			status: 'completed',
		};
		this.setState({ loading: true });
		if (obj) {
			querydata = Object.assign(obj, querydata);
		} else {
			querydata = Object.assign(this.state.filter, querydata);
		}
		const params = this.turnToUrlparam(querydata);
		fetchFer(`/api/v2/result/history?${params}`, {
			method: 'GET',
		})
			.then(res => {
				// setLoading(false);
				const { results, total } = res.data;
				this.setState({
					tableData: results,
					count: total,
					loading: false,
				});
			})
			.catch(() => {
				this.setState({ loading: false });
			})
			.finally(() => {
				this.setState({ type: 'img' });
			});
	};

	tablestate = item => {
		this.setState({
			perPage: item.perPage || 10,
			page: item.page || 10,
		});
		this.getData(item.page, item.perPage);
	};

	componentDidMount() {
		const {
			location: { search },
		} = this.props;
		const queryObj = JSON.parse(new URLSearchParams(search).get('filter'));
		this.getData(1, 10, queryObj);
	}

	render() {
		const {
			props: { className },
		} = this;

		return (
			<div className={cn(className, s.history)}>
				<Breadcrumb className={s.breadcrumb}>
					<Item disabled key="weakness">
						脆弱性监测
					</Item>
					<Item
						key={`${this.taskType}/overview${
							this.taskType === 'vul' ? '/normal' : ''
						}`}
					>
						{TASK_KEY_LABEL_MAP[this.taskType]}监测
					</Item>
					<Item key="history">历史任务</Item>
				</Breadcrumb>
				<div className={s.tableWrapper}>
					<div className={s.historyList}>历史任务列表</div>
					<TableToolbox onChange={this.handleFilterChange} />
					<Table
						pro
						loading={this.state.loading}
						empty={<EmptyData type={this.state.type} className={s.empty2} />}
						columns={this.columnsBuilder()}
						data={this.state.tableData}
					/>
					{this.state.count > 10 && (
						<Pagination
							className={s.pagination}
							pageSizeOptions={[10, 20, 50]}
							showSizeChanger
							showQuickJumper
							showTotal={total => `共${total}条`}
							total={this.state.count}
							current={this.state.page}
							page={this.state.page}
							onChange={(page, pageSize) => {
								this.tablestate({ perPage: pageSize, page });
							}}
						/>
					)}
				</div>
			</div>
		);
	}
}

export default withRouter(TaskHistory);
